/*
 *
 *  *  Copyright (C) 2018  Wanghaobin<463540703@qq.com>
 *
 *  *  AG-Enterprise 企业版源码
 *  *  郑重声明:
 *  *  如果你从其他途径获取到，请告知老A传播人，奖励1000。
 *  *  老A将追究授予人和传播人的法律责任!
 *
 *  *  This program is free software; you can redistribute it and/or modify
 *  *  it under the terms of the GNU General Public License as published by
 *  *  the Free Software Foundation; either version 2 of the License, or
 *  *  (at your option) any later version.
 *
 *  *  This program is distributed in the hope that it will be useful,
 *  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  *  GNU General Public License for more details.
 *
 *  *  You should have received a copy of the GNU General Public License along
 *  *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

package com.kuizii.base.common.oss;


import com.google.gson.Gson;
import com.kuizii.base.common.configs.oss.CloudStorageConfig;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.DownloadUrl;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.qiniu.util.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.InputStream;

import java.util.Map;

/**
 * 七牛云存储
 *
 * @author ace
 */
public class QiniuCloudStorageService extends CloudStorageService {
    private UploadManager uploadManager;


    public String getToken() {

        Auth auth = Auth.create(property.getQiniuAccessKey(), property.getQiniuSecretKey());
        return auth.uploadToken(property.getQiniuBucketName());
    }

    public CloudStorageConfig.QiniuOSSProperty getProperty() {
        return property;
    }

    public void setProperty(CloudStorageConfig.QiniuOSSProperty property) {
        this.property = property;
    }


    CloudStorageConfig.QiniuOSSProperty property;

    public QiniuCloudStorageService(CloudStorageConfig.QiniuOSSProperty property) {
        this.property = property;
        init(null);
    }

    public void init(String bucketName) {
        uploadManager = new UploadManager(new Configuration(Region.autoRegion()));

        if (StringUtils.isBlank(bucketName)) {
            bucketName = property.getQiniuBucketName();
        }
        if (StringUtils.isBlank(bucketName)) {
            throw new RuntimeException("未获取到bucketName");
        }

    }

    /**
     * 如果文件名为空，会生成hash作为文件名
     *
     * @param data 文件字节数组
     * @param path 文件路径，包含文件名
     * @return
     */
    @Override
    public String upload(byte[] data, String path) {
        try {
            Auth auth = Auth.create(property.getQiniuAccessKey(), property.getQiniuSecretKey());
            String token = auth.uploadToken(property.getQiniuBucketName());
            Response res = uploadManager.put(data, path, token);
            if (!res.isOK()) {
                throw new RuntimeException("上传七牛出错：" + res);
            }
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
            path = putRet.key;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("上传文件失败，请核对七牛配置信息");
        }

        return path;
    }

    @Override
    public String upload(InputStream inputStream, String path) {
        try {
            byte[] data = IOUtils.toByteArray(inputStream);
            return this.upload(data, path);
        } catch (IOException e) {
            throw new RuntimeException("上传文件失败");
        }
    }

    @Override
    public String uploadSuffix(byte[] data, String suffix) {
        return upload(data, getPath(property.getQiniuPrefix(), suffix));
    }

    @Override
    public String uploadSuffix(InputStream inputStream, String suffix) {
        return upload(inputStream, getPath(property.getQiniuPrefix(), suffix));
    }


    @Override
    public String getDownloadUrl(Map<String, Object> map) {

        String filename = map.get("fileName").toString();
        String attname = map.get("attname") == null ? null : map.get("attname").toString();
        Long expireInSeconds = map.get("expireInSeconds") == null ? 60 : Long.parseLong(map.get("expireInSeconds").toString());
        return getDownloadUrl(filename, attname, expireInSeconds);
    }

    /**
     * 私有文件获取下载地址
     *
     * @param fileName        七牛key 即文件名
     * @param expireInSeconds 过期时间 单位秒
     * @return
     */
    public String getDownloadUrl(String fileName, String attname, long expireInSeconds) {

        try {
            DownloadUrl url = new DownloadUrl(property.getQiniuDomain(), false, fileName);
            if (!StringUtils.isBlank(attname)) {
                // 配置 attname
                url.setAttname(attname);
            }
            Auth auth = Auth.create(property.getQiniuAccessKey(), property.getQiniuSecretKey());


            return url.buildURL(auth, (System.currentTimeMillis() / 1000L) + expireInSeconds);

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("下载地址获取失败");
        }
    }

    /**
     * 私有文件获取
     *
     * @param fileName
     * @param expireInSeconds
     * @return
     */
    public String getDownloadUrl(String fileName, long expireInSeconds) {

        try {
            DownloadUrl url = new DownloadUrl(property.getQiniuDomain(), false, fileName);

            Auth auth = Auth.create(property.getQiniuAccessKey(), property.getQiniuSecretKey());
            return url.buildURL(auth, expireInSeconds);

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("下载地址获取失败");
        }
    }

    /**
     * 公共文件地址获取
     *
     * @param fileName
     * @return
     */
    public String getDownloadUrl(String fileName) {

        try {
            DownloadUrl url = new DownloadUrl(property.getQiniuDomain(), false, fileName);

            return url.buildURL();

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("下载地址获取失败");
        }
    }
}
